package cn.com.yang.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * 信号量  AQS
 * @author 杨亿金
 * @date 2022年8月31日-下午8:36:11
 * @since 1.0.0
 */
public class TestSemaphore {
	private static Semaphore semaphore = new Semaphore(0);
	public static void main(String[] args) throws InterruptedException {
		ExecutorService executorService = Executors.newFixedThreadPool(2);
		// 线程A 添加到线程池
		executorService.submit(new Runnable() {
			@Override
			public void run() {
				try {
                    System.out.println(Thread.currentThread() + "1over");
                    // 该方法的作用是把当前Semaphore对象的信号量值增加1，如果当前有线程因为调用acquire方法被阻塞而被放入了AQS的阻塞队列，
                    // 则会根据公平策略选择一个信号量个数能被满足的线程进行激活，激活的线程会尝试获取刚增加的信号量。
                    semaphore.release();
                }catch (Exception e) {
                    e.printStackTrace();
                }
			}
		});
		// 线程B添加到线程池
		executorService.submit(new Runnable() {
			
			@Override
			public void run() {
				try {
                    System.out.println(Thread.currentThread() + "2over");
                    semaphore.release();
                    //在每个线程内部调用信号量的release方法，这相当于让计数器的值增1
                }catch (Exception e) {
                    e.printStackTrace();
                }
				
			}
		});
		// 等待子线程执行任务A完毕，返回
        semaphore.acquire(2);
 
        // 将线程C添加到线程池
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread() + "B task over");
                    semaphore.release();
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
 
        // 将线程D添加到线程池
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread() + "B task over");
                    semaphore.release();
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

		System.out.println("all child thread over");
		//关闭线程池
		executorService.shutdown();
	}
}
